定义
观察者模式又叫发布订阅模式(public/subscribe),定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
UML
示例代码
//抽象出Notifier接口,保持所有被观察者对象的引用,并管理通知 notify
abstract class INotifier {
private List observers = new ArrayList<>();
public void attach(IObserver observer) {
observers.add(observer);
}
public void detach(IObserver observer) {
observers.remove(observer);
}
public void notifyObserver() {
for (int i = 0; i < observers.size(); i++) {
observers.get(i).update();
}
}
}
// 具体的通知者 管理控制具体的观察者对象 管理自己需要变化的状态
public class ConcreteNotifier extends INotifier {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
//抽象观察者。观察者需要在得到通知后更新自己 所以需要更新方法
abstract class IObserver {
// 更新接口
public abstract void update();
}
//具体观察者 它会有一个状态 在update的时候从对应的notifier获取新状态
public class ConcreteObserver extends IObserver {
private String name;
private String observerState;
private ConcreteNotifier notifier;
public ConcreteObserver(ConcreteNotifier notifier, String name) {
// TODO Auto-generated constructor stub
this.notifier = notifier;
this.name = name;
}
@Override
public void update() {
// TODO Auto-generated method stub
observerState = notifier.getState();
System.out.println("Observer " + name + "'s new state is " + observerState);
}
}
//客户代码
public void start() {
//创建通知者
ConcreteNotifier notifier = new ConcreteNotifier();
//添加观察者
notifier.attach(new ConcreteObserver(notifier, "X"));
notifier.attach(new ConcreteObserver(notifier, "Y"));
//通知更新状态
notifier.setState("hahaha");
//告诉观察者开始改状态
notifier.notifyObserver();
}
//输出
Observer X's new state is hahaha
Observer Y's new state is hahaha
评价
一个对象改变需要同时改变其他对象的时候,且它不知道具体有多少对象有待改变时,考虑使用观察者模式。
观察者模式做的工作其实就是在解耦合,让耦合双方都依赖抽象,而不是依赖具体。从而使得各自变化都不会影响另一边变化。
但上面代码还有一个小问题,就是INotifier依赖IObserver。如果通知者和观察者互相不知道对方,由客户端来决定,那么就会更灵活。所以还需要一层解耦。